package fiado.dao.sqlserver;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import fiado.bean.Pessoa;
import fiado.exception.DaoException;
import fiado.util.DbUtilSqlServer;


public class PessoaDAO {

	private String QUERY_SEQUENCE = "select isnull(max(ID_PESSOA), 0) + 1 as NOVO_ID_PESSOA from TB_PESSOA";
	
	private String QUERY_BUSCAR_TODOS = 
			"select " +
			"	ID_PESSOA, " +
			"	NM_PRENOME, " +
			"	NM_SOBRENOME, " +
			"	DT_NASCIMENTO, " +
			"	DT_FALECIMENTO, " +
			"	FOTO, " +
			"	EMAIL, " +
			"	SEXO " +
			"from " +
			"	TB_PESSOA " +
			"order by NM_PRENOME ";
	
	private String QUERY_BUSCAR_POR_ID = 
			"select " +
			"	ID_PESSOA, " +
			"	NM_PRENOME, " +
			"	NM_SOBRENOME, " +
			"	DT_NASCIMENTO, " +
			"	DT_FALECIMENTO, " +
			"	FOTO, " +
			"	EMAIL, " +
			"	SEXO " +
			"from " +
			"	TB_PESSOA " +
			"where " +
			"	TB_PESSOA.ID_PESSOA = ? " +
			"order by NM_PRENOME ";
	
	private String QUERY_APAGAR_POR_ID = "delete from TB_PESSOA where TB_PESSOA.ID_PESSOA = ?";
	
	private String QUERY_CRIAR_PESSOA = 
			"insert into TB_PESSOA (" +
			"	ID_PESSOA, " +
			"	NM_PRENOME, " +
			"	NM_SOBRENOME, " +
			"	DT_NASCIMENTO, " +
			"	DT_FALECIMENTO," +
			"	FOTO, " +
			"	EMAIL, " +
			"	SEXO " +
			" ) " +
			"values(" +
			"	?, ?, ?, ?, ?, ?, ?, ?)" ;
	
	private String QUERY_ATUALIZAR_PESSOA = 
			"update TB_PESSOA " + 
			"set " + 
			"   NM_PRENOME = ?, " + 
			"   NM_SOBRENOME = ?, " + 
			"   DT_NASCIMENTO = ?, " + 
			"   DT_FALECIMENTO = ?, " +
			"   FOTO = ?, " + 
			"   EMAIL = ?, " +
			"	SEXO = ? " + 
			"where  " + 
			"   TB_PESSOA.ID_PESSOA = ? ";
	
	private String QUERY_BUSCAR_POR_NOME = 
			"select " +
			"	ID_PESSOA, " +
			"	NM_PRENOME, " +
			"	NM_SOBRENOME, " +
			"	DT_NASCIMENTO, " +
			"	DT_FALECIMENTO," +
			"	FOTO, " +
			"	EMAIL, " +
			"	SEXO " +
			"from " +
			"	TB_PESSOA " +
			"where " +
			"	NM_PRENOME like ? or " +
			"	NM_SOBRENOME like ? " +
			"order by NM_PRENOME ";
	
	private int getProximoValorSequence() throws DaoException {
		Connection conn = DbUtilSqlServer.getConnection();
		PreparedStatement statement = null;
		ResultSet result = null;
		int novoIdPessoa = 0;
		try {
			
			statement = conn.prepareStatement(QUERY_SEQUENCE);
			result = statement.executeQuery();
			if (result.next()) {

				novoIdPessoa = result.getInt("NOVO_ID_PESSOA");
			}
		} catch (SQLException e) {
			throw new DaoException(e);
		} finally {
			DbUtilSqlServer.close(conn, statement, result);
		}
		return novoIdPessoa;
	}
	
	/**
	 * Este metodo retorna uma lista com todos os objetos pessoa armazenados
	 * @return
	 * @throws DaoException 
	 */
	public List<Pessoa> buscarTodos() throws DaoException {
		Connection conn = DbUtilSqlServer.getConnection();
		PreparedStatement statement = null;
		ResultSet result = null;
		List<Pessoa> listaTodos = new ArrayList<Pessoa>();
		try {
			
			statement = conn.prepareStatement(QUERY_BUSCAR_TODOS);
			result = statement.executeQuery();
			while (result.next()) {
				Pessoa pessoa = getBeanFromStatement(result);
				listaTodos.add(pessoa);
			}
		} catch (SQLException e) {
			throw new DaoException(e);
		} finally {
			DbUtilSqlServer.close(conn, statement, result);
		}
		return listaTodos;
	}

	private Pessoa getBeanFromStatement(ResultSet result) throws SQLException,
			DaoException {
		Pessoa pessoa = new Pessoa();
		pessoa.setId(result.getInt("ID_PESSOA"));
		pessoa.setPrenome(result.getString("NM_PRENOME"));
		pessoa.setSobrenome(result.getString("NM_SOBRENOME"));
		pessoa.setDataNascimento(DbUtilSqlServer.getJavaDate(result, "DT_NASCIMENTO"));
		pessoa.setDataFalecimento(DbUtilSqlServer.getJavaDate(result, "DT_FALECIMENTO"));
		pessoa.setFoto(DbUtilSqlServer.getImage(result, "FOTO"));
		pessoa.setEmail(result.getString("EMAIL"));
		String sexoStr = result.getString("SEXO");
		if (sexoStr != null) {
			pessoa.setSexo(sexoStr.charAt(0));
		}
		return pessoa;
	}

	/**
	 * Este metodo retorna uma lista com todos os objetos pessoa armazenados
	 * que possuam <nome> no campo prenome ou no campo sobrenome
	 * @return
	 * @throws DaoException 
	 */
	public List<Pessoa> buscarPorNome(String nome) throws DaoException {
		nome = "%" + nome + "%";
		Connection conn = DbUtilSqlServer.getConnection();
		PreparedStatement statement = null;
		ResultSet result = null;
		List<Pessoa> listaTodos = new ArrayList<Pessoa>();
		try {
			
			statement = conn.prepareStatement(QUERY_BUSCAR_POR_NOME);
			statement.setString(1, nome);
			statement.setString(2, nome);
			result = statement.executeQuery();
			while (result.next()) {
				Pessoa pessoa = getBeanFromStatement(result);
				listaTodos.add(pessoa);
			}
		} catch (SQLException e) {
			throw new DaoException(e);
		} finally {
			DbUtilSqlServer.close(conn, statement, result);
		}
		return listaTodos;
	}
	
	/**
	 * Este metodo retorna o objeto pessoa de acordo com o id
	 * @return
	 * @throws DaoException 
	 */
	public Pessoa buscarPorId(int idPessoa) throws DaoException {
		Connection conn = DbUtilSqlServer.getConnection();
		PreparedStatement statement = null;
		ResultSet result = null;
		Pessoa pessoa = null;
		try {
			
			statement = conn.prepareStatement(QUERY_BUSCAR_POR_ID);
			statement.setInt(1, idPessoa);
			result = statement.executeQuery();
			if (result.next()) {
				pessoa = getBeanFromStatement(result);
			}
		} catch (SQLException e) {
			throw new DaoException(e);
		} finally {
			DbUtilSqlServer.close(conn, statement, result);
		}
		return pessoa;
	}
	
	/**
	 * Este metodo apaga o objeto pessoa de acordo com o id
	 * @throws DaoException 
	 */
	public void apagar(int idPessoa) throws DaoException {
		Connection conn = DbUtilSqlServer.getConnection();
		PreparedStatement statement = null;
		ResultSet result = null;
		try {
			
			statement = conn.prepareStatement(QUERY_APAGAR_POR_ID);
			statement.setInt(1, idPessoa);
			statement.execute();
			
		} catch (SQLException e) {
			throw new DaoException(e);
		} finally {
			DbUtilSqlServer.close(conn, statement, result);
		}
	}	
	
	/**
	 * Este metodo apaga o objeto pessoa
	 * @throws DaoException 
	 */
	public void apagar(Pessoa pessoa) throws DaoException {
		apagar(pessoa.getId());
	}
	
	/**
	 * Este metodo salva o objeto pessoa 
	 * @throws DaoException 
	 */
	public void salvar(Pessoa pessoa) throws DaoException {
		Connection conn = DbUtilSqlServer.getConnection();
		PreparedStatement statement = null;
		ResultSet result = null;
		byte[] byteArray = null;
		try {
			statement = conn.prepareStatement(QUERY_ATUALIZAR_PESSOA);
			
			statement.setString(1, pessoa.getPrenome());
			statement.setString(2, pessoa.getSobrenome());
			statement.setDate(3, DbUtilSqlServer.getSqlDate(pessoa.getDataNascimento()));
			statement.setDate(4, DbUtilSqlServer.getSqlDate(pessoa.getDataFalecimento()));
			//byteArray = DbUtilSqlServer.getArrayImage(pessoa.getFoto());
			byteArray = pessoa.getFoto();
			statement.setBytes(5, byteArray);
			statement.setString(6, pessoa.getEmail());
			statement.setString(7, pessoa.getSexo() + "");
			
			statement.setInt(8, pessoa.getId());

			statement.executeUpdate();
			
		} catch (SQLException e) {
			throw new DaoException(e);
		} finally {
			DbUtilSqlServer.close(conn, statement, result);
		}
	}
	
	/**
	 * Este metodo cria o objeto pessoa e retorna o objeto criado com o novo id
	 * preenchido
	 * @throws DaoException 
	 */
	public void criar(Pessoa pessoa) throws DaoException {
		int novoIdPessoa = getProximoValorSequence();

		Connection conn = DbUtilSqlServer.getConnection();
		PreparedStatement statement = null;
		ResultSet result = null;
		byte[] byteArray = null; 
		try {
			
						
			statement = conn.prepareStatement(QUERY_CRIAR_PESSOA);
			statement.setInt(1, novoIdPessoa);
			statement.setString(2, pessoa.getPrenome());
			statement.setString(3, pessoa.getSobrenome());
			statement.setDate(4, DbUtilSqlServer.getSqlDate(pessoa.getDataNascimento()));
			statement.setDate(5, DbUtilSqlServer.getSqlDate(pessoa.getDataFalecimento()));
			//byteArray = DbUtilSqlServer.getArrayImage(pessoa.getFoto());
			byteArray = pessoa.getFoto();
			statement.setBytes(6, byteArray);
			statement.setString(7, pessoa.getEmail());
			statement.setString(8, pessoa.getSexo() + "");

			statement.executeUpdate();
			
			pessoa.setId(novoIdPessoa);
			
		} catch (SQLException e) {
			throw new DaoException(e);
		} finally {
			DbUtilSqlServer.close(conn, statement, result);
		}
	}
}
